#include "StdAfx.h"
#include "MyActiveInterface.h"

// Includes for factory method.
#include "MyActiveObject.h"
#include "MyActiveHSM.h"
#include "MyActiveObjectContainer.h"
#include "MyHsmMessageHandlerAO.h"

namespace CO { namespace MyGroupNamespace { namespace MyPackageNamespace {

//
// TODO: Implement factory method to create derived type objects.
//
MyActiveInterfaceSP MyActiveInterface::Create(SubClass type)
{
	MyActiveInterfaceSP retVal;
	switch (type)
	{
	case MY_ACTIVE_OBJECT:
		retVal.reset(new MyActiveObject());
		break;
	case MY_ACTIVE_HSM:
		retVal.reset(new MyActiveHSM());
		break;
	case MY_ACTIVE_OBJECT_CONTAINER:
		retVal.reset(new MyActiveObjectContainer());
		break;
	case MY_HSM_MESSAGE_HANDLER:
		retVal.reset(new MyHsmMessageHandlerAO());
		break;
	}
	return retVal;
}

//
// TODO:  Add priority for each port in order declared, including timer.
//
const SpiFoundation::RoomFW::ActiveObject::PortPriority MyActiveInterface::PortPriorities[] = {
	PRI_CRITICAL,	// PORT_SYSTEM
	PRI_NORMAL,	// PORT_MY_PORT_1
	PRI_NORMAL,	// PORT_MY_PORT_2
	PRI_HIGH,	// PORT_MY_PORT_3
	PRI_HIGH	// PORT_TIMER
};
const size_t MyActiveInterface::PortPrioritiesSize = sizeof(MyActiveInterface::PortPriorities) / sizeof(IActiveObject::PortPriority);
BOOST_STATIC_ASSERT(MyActiveInterface::PortPrioritiesSize == MyActiveInterface::PORT_COUNT + 1);

MyActiveInterface::MyActiveInterface(void) :
	//
	// TODO:  Initialize protocol attributes.
	//
	systemProtocol_(true),	// true = conjugated.
	myProtocol_1_(false),	// false = not conjugated.
	myProtocol_2_(true)		// true = conjugated.
{
}

MyActiveInterface::~MyActiveInterface(void)
{
}

const char* MyActiveInterface::getPortName(size_t portIndex) const
{
	//
	// TODO:  Add text for each port name for debugging.
	//
	const char* retVal = "UNKNOWN_PORT";
	switch (portIndex)
	{
	case PORT_SYSTEM:
		retVal = "PORT_SYSTEM";
		break;
	case PORT_MY_PORT_1:
		retVal = "PORT_MY_PORT_1";
		break;
	case PORT_MY_PORT_2:
		retVal = "PORT_MY_PORT_2";
		break;
	case PORT_MY_PORT_3:
		retVal = "PORT_MY_PORT_3";
		break;
	case PORT_TIMER:
		retVal = "PORT_TIMER";
		break;
	//default:
	//	ASSERT(false); // Invalid port.
	};
	return retVal;
}

SpiFoundation::RoomFW::IContractCheckerSPC
MyActiveInterface::getContractChecker(SpiFoundation::RoomFW::PortIndex portIndex) const
{
	//
	// TODO:  Return the contract checker for each port.
	//
	SpiFoundation::RoomFW::IContractCheckerSPC retVal;
	switch (portIndex.port())
	{
	case PORT_SYSTEM:
		retVal = SpiFoundation::RoomFW::IContractCheckerSPC(&systemProtocol_, SystemManagerProtocolNullDeleter());
		break;
	case PORT_MY_PORT_1:
		retVal = SpiFoundation::RoomFW::IContractCheckerSPC(&myProtocol_1_, MyProtocolNullDeleter());
		break;
	case PORT_MY_PORT_2:
		retVal = SpiFoundation::RoomFW::IContractCheckerSPC(&myProtocol_2_, MyProtocolNullDeleter());
		break;
	case PORT_MY_PORT_3:
		retVal = SpiFoundation::RoomFW::IContractCheckerSPC(&myProtocol_2_, MyProtocolNullDeleter());
		break;
	//default:
	//	ASSERT(false); // Invalid port.
	}
	return retVal;
}

SpiFoundation::RoomFW::PortIndex::PrimaryIndex MyActiveInterface::getSystemPort(void) const
{
	return PORT_SYSTEM;
}


}}} // End namespace
